﻿using System;
using System.Collections.Generic;

namespace FadeLang.VirtualMachine
{
    internal class Optimizer
    {
        private static bool IsNumber(dynamic a) {
            return a is short || a is int || a is long
                   || a is float || a is double;
        }

        private static void ConstantFolding(IList<dynamic> opcodeList) {
            var i = 0;
            while (i < opcodeList.Count - 2) {
                var op1 = opcodeList[i];
                var op2 = opcodeList[i + 1];
                var op3 = opcodeList[i + 2];
                if (IsNumber(op1) && IsNumber(op2)
                        && (op3 is OpCode 
                        && (op3 == OpCode.Add || op3 == OpCode.Sub || op3 == OpCode.Mul || op3 == OpCode.Div))) {
                    dynamic result = null;
                    switch ((OpCode)op3) {
                        case OpCode.Add:
                            result = op1 + op2;
                            break;
                        case OpCode.Sub:
                            result = op1 - op2;
                            break;
                        case OpCode.Mul:
                            result = op1 * op2;
                            break;
                        case OpCode.Div:
                            result = op1 / op2;
                            break;
                    }
                    opcodeList[i] = result;
                    opcodeList.RemoveAt(i + 1);
                    opcodeList.RemoveAt(i + 1);
                    i = 0;
                }
                else {
                    i++;
                }
            }
        }

        public static void Optimize(List<dynamic> opcodeList) {
            ConstantFolding(opcodeList);
        }
    }
}